/*
 * MainFrame.cpp
 *
 *  Created on: 2012-12-24
 *      Author: lijian
 */

#include "MainFrame.h"
#include <vector>
#include <string>
#include "Utra.h"
#include <string.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include<cstdlib>
#include <wx/msgdlg.h>
#include <wx/wx.h>
#include "dropdown.xpm"
#include <stdexcept>
#include "CharChangeUtil.h"

using namespace std;
//EVT_MENU(wxID_ANY, MainFrame::OnMenu)
BEGIN_EVENT_TABLE(MainFrame, wxFrame) EVT_THREAD(WORKER_EVENT, MainFrame::OnWorkerEvent)
END_EVENT_TABLE()

typedef struct {
	int rate;
	char* name;
} buad_t;

//int buadRates[] = { B1200, B1800, B2400, B4800, B9600, B19200, B38400,B57600, B115200};

buad_t buadRates[] = { { B1200, "1200" }, { B1800, "1800" }, { B2400, "2400" },
		{ B4800, "4800" }, { B9600, "9600" }, { B19200, "19200" }, { B38400,
				"38400" }, { B57600, "57600" }, { B115200, "115200" } };

MainFrame::MainFrame(wxWindow* parent, wxWindowID id, const wxString& title,
		const wxPoint& pos, const wxSize& size, long style) :
		MainFrameBase(parent, id, title, pos, size, style) {

	wxBitmap dropdown(dropdown_xpm);
	//	m_btn_showPort = new wxBitmapButton( this, wxID_ANY, wxBitmap(dropdown_xpm), wxDefaultPosition, wxSize( -1,20 ), wxBU_AUTODRAW|wxSIMPLE_BORDER );
	m_btn_showPort->SetBitmap(dropdown);

	for (unsigned int i = 0; i < sizeof(buadRates) / sizeof(buad_t); i++) {
		m_choice_buadRate->Append(wxString(buadRates[i].name));
	}
	m_choice_buadRate->SetSelection(4);
	m_opend = false;
	m_recvCount = 0;
	m_sendCount = 0;
	m_hexFormat = true;
	m_textCtrl_send->SetFocus();

	m_monitorThread = NULL;
	static const int widthsFor3Fields[] = { 200, 100, 100 };
	m_statusBar->SetFieldsCount(3, widthsFor3Fields);
	changeUartState();
	changeCountState();
}

MainFrame::~MainFrame() {
}

void MainFrame::changeControl() {
	if (m_opend) {
		m_choice_buadRate->Disable();
		m_choice_dataBits->Disable();
		m_choice_parity->Disable();
		m_choice_stopBits->Disable();
		m_textCtrl_port->Disable();
		m_btn_showPort->Disable();
		m_btn_sendData->Enable();
	} else {
		m_choice_buadRate->Enable();
		m_choice_dataBits->Enable();
		m_choice_parity->Enable();
		m_choice_stopBits->Enable();
		m_textCtrl_port->Enable();
		m_btn_showPort->Enable();
		m_btn_sendData->Disable();
	}
}

void MainFrame::changeUartState() {
	wxString s1;
	if (!m_opend) {
		s1 = wxString::Format("State:%s", wxT("close"));
		m_statusBar->SetStatusText(s1, 0);
	} else {
		s1 = wxString::Format("State:%s: %s, %s, %s, %s %s", "com1", buadRate,
				parrity.SubString(0, 0), databits, stopBits, "open");
	}
	m_statusBar->SetStatusText(s1, 0);

}

void MainFrame::changeCountState() {

	m_statusBar->SetStatusText(wxString::Format("RX:%d", m_recvCount), 1);
	m_statusBar->SetStatusText(wxString::Format("TX:%d", m_sendCount), 2);

	wxString rc = wxString::Format(wxT("%i"), m_recvCount);
	m_txt_RecvCount->SetValue(rc);
	wxString sc = wxString::Format(wxT("%i"), m_sendCount);
	m_txt_sendCount->SetValue(sc);
}

void MainFrame::onOpenUtra(wxCommandEvent& event) {

	if (!m_opend) {
		wxString port = m_textCtrl_port->GetValue();
		//    wxString port=wxT("/dev/");
		buadRate = m_choice_buadRate->GetStringSelection();
		databits = m_choice_dataBits->GetStringSelection();
		stopBits = m_choice_stopBits->GetStringSelection();
		parrity = m_choice_parity->GetStringSelection();

		UtraConfig config;
		config.port = port.ToStdString();

		for (unsigned int i = 0; i < sizeof(buadRates) / sizeof(buad_t); i++) {
			if(strcmp(buadRates[i].name, buadRate.c_str())==0){
				config.buadRate=buadRates[i].rate;
				break;
			}
		}

		long int tmp_l;
		databits.ToLong(&tmp_l, 10);
		config.dataBits = (unsigned char) tmp_l;
		stopBits.ToLong(&tmp_l, 10);
		config.stopBits = (unsigned char) tmp_l;

		if (parrity == wxT("None")) {
			config.parity = None;
		} else if (parrity == wxT("Odd")) {
			config.parity = Odd;
		} else if (parrity == wxT("Even")) {
			config.parity = Even;
		} else {

		}

		try {
			m_utra.setConfig(config);
			m_utra.open();

			m_monitorThread = new UtraMonitorThread(&m_utra, this);
			if (m_monitorThread->Create() != wxTHREAD_NO_ERROR) {
				runtime_error re("Can’t create thread!");
				throw re;
			}
			m_monitorThread->Run();

			m_btn_open->SetLabel(wxT("关闭"));
			m_opend = !m_opend;
		} catch (exception& e) {
			wxMessageBox(e.what(), "", wxOK | wxICON_EXCLAMATION, this);
			m_btn_open->SetValue(false);
		}
	} else {
		if (m_monitorThread != NULL) {
			m_monitorThread->stop();
		}
		m_btn_open->SetLabel(wxT("打开"));
		m_opend = !m_opend;
	}
	changeControl();
	changeUartState();
	changeCountState();
}

void MainFrame::onSendData(wxCommandEvent& event) {
	if (m_hexFormat) {
		int size = m_utra.sendHex(m_textCtrl_send->GetValue().ToStdString());
		m_sendCount += size;
	} else {
		int size = m_utra.sendString(m_textCtrl_send->GetValue().ToStdString());
		m_sendCount += size;
	}
	changeCountState();
}

void MainFrame::onShowPorts(wxCommandEvent &event) {
	wxMenu* pMenu = new wxMenu();
	// We have to start with id 1 since menu items with id 0 don't work under OS X

	vector<string> ports = Uart::get_all_utras();
	for (vector<string>::size_type i = 0; i < ports.size(); i++) {
		//    		m_comboPort->Append(ports[i]);
		pMenu->Append((int) i + 1, ports[i]);
	}

	pMenu->Connect(wxEVT_COMMAND_MENU_SELECTED,
			wxCommandEventHandler( MainFrame::OnMenu), NULL, this);

	//	XRCCTRL(*this, "ID_QUICKCONNECT_DROPDOWN", wxButton)->PopupMenu(pMenu);

	this->m_btn_showPort->PopupMenu(pMenu);
	delete pMenu;
}

void MainFrame::OnMenu(wxCommandEvent &event) {
	const int id = event.GetId();
	wxObject* obj = event.GetEventObject();
	wxMenu* menu = (wxMenu*) obj;
	wxMenuItem* item = menu->FindChildItem(id);
	m_textCtrl_port->SetValue(item->GetItemLabelText());
}

void MainFrame::onClearRecv(wxCommandEvent &event) {
	m_textCtrl_recv->Clear();
}

void MainFrame::onClearSend(wxCommandEvent &event) {
	m_textCtrl_send->Clear();
}

void MainFrame::onResetCount(wxCommandEvent &event) {
	m_recvCount = 0;
	m_sendCount = 0;
	changeCountState();
}

void MainFrame::onHexFormatChange(wxCommandEvent &event) {
	m_checkBox_hexsend->SetValue(!m_hexFormat);
	m_checkBox_hexshow->SetValue(!m_hexFormat);
	m_hexFormat = !m_hexFormat;
}

void MainFrame::OnWorkerEvent(wxThreadEvent &event) {
	UtraThreadEvent& ea = (UtraThreadEvent&) event;
	if (m_hexFormat) {
		string str = CharChangeUtil::hexToString((unsigned char*) ea.getData(),
				ea.getSize());
		wxString wxs = wxString(str);
		this->m_textCtrl_recv->AppendText(str);
	} else {
		string str(ea.getData());
		wxString wxs = wxString(str);
		this->m_textCtrl_recv->AppendText(str);
	}

	m_recvCount += ea.getSize();
	changeCountState();
}
